/*
 * JSmugmugBackupView.java
 */

package jSmugmugBackup.view.ng;

import jSmugmugBackup.config.GlobalConfig;
import jSmugmugBackup.model.*;
import jSmugmugBackup.model.accountLayer.*;
import jSmugmugBackup.model.queue.TransferQueueItemActionEnum;
import jSmugmugBackup.view.*;

import java.util.Vector;
import javax.swing.tree.TreeModel;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.DefaultComboBoxModel;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

/**
 * The application's main frame.
 */
public class SwingViewNG extends FrameView implements IView
{

    public SwingViewNG(SingleFrameApplication app)
    {
        super(app);

        initComponents();

        // status bar initialization - message timeout, idle icon and busy animation, etc
        ResourceMap resourceMap = getResourceMap();
        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
        messageTimer = new Timer(messageTimeout, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                statusMessageLabel.setText("");
            }
        });
        messageTimer.setRepeats(false);
        int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
        for (int i = 0; i < busyIcons.length; i++) {
            busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
        }
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
                statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
            }
        });
        idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
        statusAnimationLabel.setIcon(idleIcon);
        progressBar.setVisible(false);

        // connecting action tasks to status bar via TaskMonitor
        TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
        taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                String propertyName = evt.getPropertyName();
                if ("started".equals(propertyName)) {
                    if (!busyIconTimer.isRunning()) {
                        statusAnimationLabel.setIcon(busyIcons[0]);
                        busyIconIndex = 0;
                        busyIconTimer.start();
                    }
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(true);
                } else if ("done".equals(propertyName)) {
                    busyIconTimer.stop();
                    statusAnimationLabel.setIcon(idleIcon);
                    progressBar.setVisible(false);
                    progressBar.setValue(0);
                } else if ("message".equals(propertyName)) {
                    String text = (String)(evt.getNewValue());
                    statusMessageLabel.setText((text == null) ? "" : text);
                    messageTimer.restart();
                } else if ("progress".equals(propertyName)) {
                    int value = (Integer)(evt.getNewValue());
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(false);
                    progressBar.setValue(value);
                }
            }
        });
    }

    @Action
    public void showAboutBox() {
        if (aboutBox == null) {
            JFrame mainFrame = SwingViewNGStarterApp.getApplication().getMainFrame();
            aboutBox = new SwingViewNGAboutBox(mainFrame);
            aboutBox.setLocationRelativeTo(mainFrame);
        }
        SwingViewNGStarterApp.getApplication().show(aboutBox);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        mainLoginButton = new javax.swing.JButton();
        mainLogtextareaScrollPane = new javax.swing.JScrollPane();
        logTextArea = new javax.swing.JTextArea();
        mainAccountScrollPane = new javax.swing.JScrollPane();
        mainAccountTree = new javax.swing.JTree();
        mainUploadButton = new javax.swing.JButton();
        mainDownloadButton = new javax.swing.JButton();
        mainExitButton = new javax.swing.JButton();
        mainSyncProcessQueueButton = new javax.swing.JButton();
        mainVerifyButton = new javax.swing.JButton();
        mainSortButton = new javax.swing.JButton();
        mainAsyncProcessQueueButton = new javax.swing.JButton();
        mainTaggingButton = new javax.swing.JButton();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        loginMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenu helpMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
        statusPanel = new javax.swing.JPanel();
        javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
        statusMessageLabel = new javax.swing.JLabel();
        statusAnimationLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();
        downloadDialog = new javax.swing.JDialog();
        folderLabel = new javax.swing.JLabel();
        folderTextField = new javax.swing.JTextField();
        folderButton = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JSeparator();
        okButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        loginDialog = new javax.swing.JDialog();
        loginUsernameLabel = new javax.swing.JLabel();
        loginPasswordLabel = new javax.swing.JLabel();
        loginUsernameTextField = new javax.swing.JTextField();
        loginPasswordPasswordField = new javax.swing.JPasswordField();
        loginCancelButton = new javax.swing.JButton();
        loginOkButton = new javax.swing.JButton();
        waitDialog = new javax.swing.JDialog();
        waitMessageLabel = new javax.swing.JLabel();
        transferDialog = new javax.swing.JDialog();
        transferActionLabel = new javax.swing.JLabel();
        transferFolderLabel = new javax.swing.JLabel();
        transferFolderTextField = new javax.swing.JTextField();
        transferSelectFolderButton = new javax.swing.JButton();
        transferSeparator1 = new javax.swing.JSeparator();
        transferToLabel = new javax.swing.JLabel();
        transferCategoryLabel = new javax.swing.JLabel();
        transferSubcategoryLabel = new javax.swing.JLabel();
        transferAlbumLabel = new javax.swing.JLabel();
        transferSubcategoryComboBox = new javax.swing.JComboBox();
        transferCategoryComboBox = new javax.swing.JComboBox();
        transferAlbumComboBox = new javax.swing.JComboBox();
        transferScrollPane = new javax.swing.JScrollPane();
        transferTree = new javax.swing.JTree();
        transferSeparator2 = new javax.swing.JSeparator();
        transferOptionsLabel = new javax.swing.JLabel();
        transferCancelButton = new javax.swing.JButton();
        transferOkButton = new javax.swing.JButton();
        transferFileChooser = new javax.swing.JFileChooser();

        mainPanel.setName("mainPanel"); // NOI18N

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(jSmugmugBackup.view.ng.SwingViewNGStarterApp.class).getContext().getResourceMap(SwingViewNG.class);
        mainLoginButton.setText(resourceMap.getString("mainLoginButton.text")); // NOI18N
        mainLoginButton.setName("mainLoginButton"); // NOI18N

        mainLogtextareaScrollPane.setName("mainLogtextareaScrollPane"); // NOI18N

        logTextArea.setColumns(20);
        logTextArea.setRows(5);
        logTextArea.setName("logTextArea"); // NOI18N
        mainLogtextareaScrollPane.setViewportView(logTextArea);

        mainAccountScrollPane.setName("mainAccountScrollPane"); // NOI18N

        javax.swing.tree.DefaultMutableTreeNode treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("root");
        mainAccountTree.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1));
        mainAccountTree.setName("mainAccountTree"); // NOI18N
        mainAccountScrollPane.setViewportView(mainAccountTree);

        mainUploadButton.setText(resourceMap.getString("mainUploadButton.text")); // NOI18N
        mainUploadButton.setEnabled(false);
        mainUploadButton.setName("mainUploadButton"); // NOI18N

        mainDownloadButton.setText(resourceMap.getString("mainDownloadButton.text")); // NOI18N
        mainDownloadButton.setEnabled(false);
        mainDownloadButton.setName("mainDownloadButton"); // NOI18N

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(jSmugmugBackup.view.ng.SwingViewNGStarterApp.class).getContext().getActionMap(SwingViewNG.class, this);
        mainExitButton.setAction(actionMap.get("mainExitButtonActionPerformed")); // NOI18N
        mainExitButton.setText(resourceMap.getString("mainExitButton.text")); // NOI18N
        mainExitButton.setName("mainExitButton"); // NOI18N

        mainSyncProcessQueueButton.setText(resourceMap.getString("mainSyncProcessQueueButton.text")); // NOI18N
        mainSyncProcessQueueButton.setName("mainSyncProcessQueueButton"); // NOI18N

        mainVerifyButton.setText(resourceMap.getString("mainVerifyButton.text")); // NOI18N
        mainVerifyButton.setEnabled(false);
        mainVerifyButton.setName("mainVerifyButton"); // NOI18N

        mainSortButton.setText(resourceMap.getString("mainSortButton.text")); // NOI18N
        mainSortButton.setEnabled(false);
        mainSortButton.setName("mainSortButton"); // NOI18N

        mainAsyncProcessQueueButton.setAction(actionMap.get("mainProcessQueueButtonActionPerformed")); // NOI18N
        mainAsyncProcessQueueButton.setText(resourceMap.getString("mainAsyncProcessQueueButton.text")); // NOI18N
        mainAsyncProcessQueueButton.setName("mainAsyncProcessQueueButton"); // NOI18N

        mainTaggingButton.setText(resourceMap.getString("mainTaggingButton.text")); // NOI18N
        mainTaggingButton.setEnabled(false);
        mainTaggingButton.setName("mainTaggingButton"); // NOI18N

        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(mainLogtextareaScrollPane, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 495, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, mainPanelLayout.createSequentialGroup()
                        .addComponent(mainAccountScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 359, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(mainTaggingButton, javax.swing.GroupLayout.DEFAULT_SIZE, 130, Short.MAX_VALUE)
                            .addComponent(mainExitButton, javax.swing.GroupLayout.DEFAULT_SIZE, 130, Short.MAX_VALUE)
                            .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                .addComponent(mainDownloadButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(mainUploadButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(mainLoginButton, javax.swing.GroupLayout.DEFAULT_SIZE, 130, Short.MAX_VALUE)
                                .addComponent(mainSyncProcessQueueButton, javax.swing.GroupLayout.DEFAULT_SIZE, 116, Short.MAX_VALUE)
                                .addComponent(mainVerifyButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(mainSortButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                            .addComponent(mainAsyncProcessQueueButton, javax.swing.GroupLayout.DEFAULT_SIZE, 130, Short.MAX_VALUE))))
                .addGap(55, 55, 55))
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addComponent(mainAccountScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 335, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED))
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addComponent(mainLoginButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(mainUploadButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(mainDownloadButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(mainVerifyButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(mainSortButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(mainTaggingButton)
                        .addGap(25, 25, 25)
                        .addComponent(mainSyncProcessQueueButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(mainAsyncProcessQueueButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(mainExitButton)
                        .addGap(21, 21, 21)))
                .addComponent(mainLogtextareaScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 110, Short.MAX_VALUE)
                .addContainerGap())
        );

        menuBar.setName("menuBar"); // NOI18N

        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N

        loginMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_L, java.awt.event.InputEvent.CTRL_MASK));
        loginMenuItem.setMnemonic('L');
        loginMenuItem.setText(resourceMap.getString("loginMenuItem.text")); // NOI18N
        loginMenuItem.setName("loginMenuItem"); // NOI18N
        fileMenu.add(loginMenuItem);

        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
        helpMenu.setName("helpMenu"); // NOI18N

        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        statusPanel.setName("statusPanel"); // NOI18N
        statusPanel.setPreferredSize(new java.awt.Dimension(521, 30));

        statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N

        statusMessageLabel.setName("statusMessageLabel"); // NOI18N

        statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N

        progressBar.setName("progressBar"); // NOI18N

        javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(statusPanelSeparator, javax.swing.GroupLayout.DEFAULT_SIZE, 562, Short.MAX_VALUE)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(statusMessageLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 376, Short.MAX_VALUE)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(statusAnimationLabel)
                .addContainerGap())
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(statusMessageLabel)
                    .addComponent(statusAnimationLabel)
                    .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(3, 3, 3))
        );

        downloadDialog.setModal(true);
        downloadDialog.setName("downloadDialog"); // NOI18N

        folderLabel.setText(resourceMap.getString("folderLabel.text")); // NOI18N
        folderLabel.setName("folderLabel"); // NOI18N

        folderTextField.setText(resourceMap.getString("folderTextField.text")); // NOI18N
        folderTextField.setName("folderTextField"); // NOI18N

        folderButton.setText(resourceMap.getString("folderButton.text")); // NOI18N
        folderButton.setName("folderButton"); // NOI18N

        jSeparator1.setName("jSeparator1"); // NOI18N

        okButton.setText(resourceMap.getString("okButton.text")); // NOI18N
        okButton.setName("okButton"); // NOI18N

        cancelButton.setText(resourceMap.getString("cancelButton.text")); // NOI18N
        cancelButton.setName("cancelButton"); // NOI18N

        javax.swing.GroupLayout downloadDialogLayout = new javax.swing.GroupLayout(downloadDialog.getContentPane());
        downloadDialog.getContentPane().setLayout(downloadDialogLayout);
        downloadDialogLayout.setHorizontalGroup(
            downloadDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(downloadDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(downloadDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(downloadDialogLayout.createSequentialGroup()
                        .addGroup(downloadDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 349, Short.MAX_VALUE)
                            .addGroup(downloadDialogLayout.createSequentialGroup()
                                .addComponent(folderLabel)
                                .addGap(18, 18, 18)
                                .addComponent(folderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 181, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(folderButton)))
                        .addContainerGap())
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, downloadDialogLayout.createSequentialGroup()
                        .addComponent(cancelButton)
                        .addGap(78, 78, 78)
                        .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(70, 70, 70))))
        );
        downloadDialogLayout.setVerticalGroup(
            downloadDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(downloadDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(downloadDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(folderLabel)
                    .addComponent(folderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(folderButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGroup(downloadDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(downloadDialogLayout.createSequentialGroup()
                        .addGap(245, 245, 245)
                        .addComponent(okButton)
                        .addContainerGap(69, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, downloadDialogLayout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cancelButton)
                        .addGap(48, 48, 48))))
        );

        loginDialog.setModal(true);
        loginDialog.setName("loginDialog"); // NOI18N
        loginDialog.setResizable(false);

        loginUsernameLabel.setText(resourceMap.getString("loginUsernameLabel.text")); // NOI18N
        loginUsernameLabel.setName("loginUsernameLabel"); // NOI18N

        loginPasswordLabel.setText(resourceMap.getString("loginPasswordLabel.text")); // NOI18N
        loginPasswordLabel.setName("loginPasswordLabel"); // NOI18N

        loginUsernameTextField.setText(resourceMap.getString("loginUsernameTextField.text")); // NOI18N
        loginUsernameTextField.setName("loginUsernameTextField"); // NOI18N

        loginPasswordPasswordField.setText(resourceMap.getString("loginPasswordPasswordField.text")); // NOI18N
        loginPasswordPasswordField.setName("loginPasswordPasswordField"); // NOI18N

        loginCancelButton.setAction(actionMap.get("loginCancelButtonActionPerformed")); // NOI18N
        loginCancelButton.setText(resourceMap.getString("loginCancelButton.text")); // NOI18N
        loginCancelButton.setName("loginCancelButton"); // NOI18N

        loginOkButton.setAction(actionMap.get("loginOkButtonActionPerformend")); // NOI18N
        loginOkButton.setText(resourceMap.getString("loginOkButton.text")); // NOI18N
        loginOkButton.setName("loginOkButton"); // NOI18N

        javax.swing.GroupLayout loginDialogLayout = new javax.swing.GroupLayout(loginDialog.getContentPane());
        loginDialog.getContentPane().setLayout(loginDialogLayout);
        loginDialogLayout.setHorizontalGroup(
            loginDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(loginDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(loginDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(loginDialogLayout.createSequentialGroup()
                        .addGroup(loginDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(loginUsernameLabel)
                            .addComponent(loginPasswordLabel))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(loginDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(loginPasswordPasswordField)
                            .addComponent(loginUsernameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 144, Short.MAX_VALUE)))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, loginDialogLayout.createSequentialGroup()
                        .addComponent(loginCancelButton)
                        .addGap(18, 18, 18)
                        .addComponent(loginOkButton, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(12, Short.MAX_VALUE))
        );
        loginDialogLayout.setVerticalGroup(
            loginDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(loginDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(loginDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(loginUsernameLabel)
                    .addComponent(loginUsernameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(loginDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(loginPasswordLabel)
                    .addComponent(loginPasswordPasswordField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(loginDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(loginOkButton)
                    .addComponent(loginCancelButton))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        waitDialog.setName("waitDialog"); // NOI18N
        waitDialog.setResizable(false);

        waitMessageLabel.setText(resourceMap.getString("waitMessageLabel.text")); // NOI18N
        waitMessageLabel.setName("waitMessageLabel"); // NOI18N

        javax.swing.GroupLayout waitDialogLayout = new javax.swing.GroupLayout(waitDialog.getContentPane());
        waitDialog.getContentPane().setLayout(waitDialogLayout);
        waitDialogLayout.setHorizontalGroup(
            waitDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(waitDialogLayout.createSequentialGroup()
                .addGap(46, 46, 46)
                .addComponent(waitMessageLabel)
                .addContainerGap(239, Short.MAX_VALUE))
        );
        waitDialogLayout.setVerticalGroup(
            waitDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(waitDialogLayout.createSequentialGroup()
                .addGap(54, 54, 54)
                .addComponent(waitMessageLabel)
                .addContainerGap(107, Short.MAX_VALUE))
        );

        transferDialog.setTitle(resourceMap.getString("transferDialog.title")); // NOI18N
        transferDialog.setModal(true);
        transferDialog.setName("transferDialog"); // NOI18N

        transferActionLabel.setText(resourceMap.getString("transferActionLabel.text")); // NOI18N
        transferActionLabel.setName("transferActionLabel"); // NOI18N

        transferFolderLabel.setText(resourceMap.getString("transferFolderLabel.text")); // NOI18N
        transferFolderLabel.setName("transferFolderLabel"); // NOI18N

        transferFolderTextField.setText(resourceMap.getString("transferFolderTextField.text")); // NOI18N
        transferFolderTextField.setName("transferFolderTextField"); // NOI18N

        transferSelectFolderButton.setAction(actionMap.get("transferSelectFolderButtonActionPerformed")); // NOI18N
        transferSelectFolderButton.setText(resourceMap.getString("transferSelectFolderButton.text")); // NOI18N
        transferSelectFolderButton.setName("transferSelectFolderButton"); // NOI18N

        transferSeparator1.setName("transferSeparator1"); // NOI18N

        transferToLabel.setText(resourceMap.getString("transferToLabel.text")); // NOI18N
        transferToLabel.setName("transferToLabel"); // NOI18N

        transferCategoryLabel.setText(resourceMap.getString("transferCategoryLabel.text")); // NOI18N
        transferCategoryLabel.setName("transferCategoryLabel"); // NOI18N

        transferSubcategoryLabel.setText(resourceMap.getString("transferSubcategoryLabel.text")); // NOI18N
        transferSubcategoryLabel.setName("transferSubcategoryLabel"); // NOI18N

        transferAlbumLabel.setText(resourceMap.getString("transferAlbumLabel.text")); // NOI18N
        transferAlbumLabel.setName("transferAlbumLabel"); // NOI18N

        transferSubcategoryComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "<auto>" }));
        transferSubcategoryComboBox.setName("transferSubcategoryComboBox"); // NOI18N
        transferSubcategoryComboBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                transferSubcategoryComboBoxItemStateChanged(evt);
            }
        });

        transferCategoryComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "<auto>" }));
        transferCategoryComboBox.setName("transferCategoryComboBox"); // NOI18N
        transferCategoryComboBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                transferCategoryComboBoxItemStateChanged(evt);
            }
        });

        transferAlbumComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "<auto>" }));
        transferAlbumComboBox.setName("transferAlbumComboBox"); // NOI18N
        transferAlbumComboBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                transferAlbumComboBoxItemStateChanged(evt);
            }
        });

        transferScrollPane.setName("transferScrollPane"); // NOI18N

        transferTree.setName("transferTree"); // NOI18N
        transferScrollPane.setViewportView(transferTree);

        transferSeparator2.setName("transferSeparator2"); // NOI18N

        transferOptionsLabel.setText(resourceMap.getString("transferOptionsLabel.text")); // NOI18N
        transferOptionsLabel.setName("transferOptionsLabel"); // NOI18N

        transferCancelButton.setAction(actionMap.get("transferCancelButtonActionPerformed")); // NOI18N
        transferCancelButton.setText(resourceMap.getString("transferCancelButton.text")); // NOI18N
        transferCancelButton.setName("transferCancelButton"); // NOI18N

        transferOkButton.setAction(actionMap.get("transferOkButtonActionPerformed")); // NOI18N
        transferOkButton.setText(resourceMap.getString("transferOkButton.text")); // NOI18N
        transferOkButton.setName("transferOkButton"); // NOI18N

        javax.swing.GroupLayout transferDialogLayout = new javax.swing.GroupLayout(transferDialog.getContentPane());
        transferDialog.getContentPane().setLayout(transferDialogLayout);
        transferDialogLayout.setHorizontalGroup(
            transferDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(transferDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(transferDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(transferActionLabel)
                    .addComponent(transferToLabel)
                    .addComponent(transferOptionsLabel)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, transferDialogLayout.createSequentialGroup()
                        .addGroup(transferDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(transferSeparator2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 410, Short.MAX_VALUE)
                            .addComponent(transferScrollPane, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 410, Short.MAX_VALUE)
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, transferDialogLayout.createSequentialGroup()
                                .addGap(12, 12, 12)
                                .addGroup(transferDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(transferSubcategoryLabel)
                                    .addComponent(transferCategoryLabel)
                                    .addComponent(transferAlbumLabel))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(transferDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(transferCategoryComboBox, 0, 308, Short.MAX_VALUE)
                                    .addComponent(transferAlbumComboBox, 0, 308, Short.MAX_VALUE)
                                    .addComponent(transferSubcategoryComboBox, 0, 308, Short.MAX_VALUE)))
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, transferDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                .addComponent(transferSeparator1, javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(javax.swing.GroupLayout.Alignment.LEADING, transferDialogLayout.createSequentialGroup()
                                    .addComponent(transferFolderLabel)
                                    .addGap(18, 18, 18)
                                    .addComponent(transferFolderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 176, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addGap(18, 18, 18)
                                    .addComponent(transferSelectFolderButton)))
                            .addComponent(transferOkButton, javax.swing.GroupLayout.PREFERRED_SIZE, 54, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(71, 71, 71)))
                .addContainerGap())
            .addGroup(transferDialogLayout.createSequentialGroup()
                .addGap(62, 62, 62)
                .addComponent(transferCancelButton)
                .addContainerGap(380, Short.MAX_VALUE))
        );
        transferDialogLayout.setVerticalGroup(
            transferDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(transferDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(transferActionLabel)
                .addGap(18, 18, 18)
                .addGroup(transferDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(transferFolderLabel)
                    .addComponent(transferFolderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(transferSelectFolderButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(transferSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(transferToLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(transferDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(transferCategoryLabel)
                    .addComponent(transferCategoryComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(transferDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(transferSubcategoryLabel)
                    .addComponent(transferSubcategoryComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(transferDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(transferAlbumLabel)
                    .addComponent(transferAlbumComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(transferScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(transferSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(transferOptionsLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 44, Short.MAX_VALUE)
                .addGroup(transferDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(transferCancelButton)
                    .addComponent(transferOkButton))
                .addGap(29, 29, 29))
        );

        transferFileChooser.setFileSelectionMode(javax.swing.JFileChooser.DIRECTORIES_ONLY);
        transferFileChooser.setName("transferFileChooser"); // NOI18N

        setComponent(mainPanel);
        setMenuBar(menuBar);
        setStatusBar(statusPanel);
    }// </editor-fold>//GEN-END:initComponents

    private void transferCategoryComboBoxItemStateChanged(java.awt.event.ItemEvent evt)//GEN-FIRST:event_transferCategoryComboBoxItemStateChanged
    {//GEN-HEADEREND:event_transferCategoryComboBoxItemStateChanged
        // TODO add your handling code here:
        
        //this.log.printLogLine((String)evt.getItem());
        //this.log.printLogLine("selected: " + (String)this.transferCategoryComboBox.getSelectedItem() + "." + (String)this.transferSubcategoryComboBox.getSelectedItem() + "." + (String)this.transferAlbumComboBox.getSelectedItem());

        String categoryFilter = (String)this.transferCategoryComboBox.getSelectedItem();
        String subcategoryFilter = (String)this.transferSubcategoryComboBox.getSelectedItem();
        this.transferUpdateTransferDestinationComboBoxes(categoryFilter, this.transferComboBoxWildcardElement, this.transferComboBoxWildcardElement);
        this.transferUpdateTransferTree(categoryFilter, this.transferComboBoxWildcardElement, this.transferComboBoxWildcardElement);
    }//GEN-LAST:event_transferCategoryComboBoxItemStateChanged

    private void transferSubcategoryComboBoxItemStateChanged(java.awt.event.ItemEvent evt)//GEN-FIRST:event_transferSubcategoryComboBoxItemStateChanged
    {//GEN-HEADEREND:event_transferSubcategoryComboBoxItemStateChanged
        // TODO add your handling code here:
        //this.log.printLogLine((String)evt.getItem());
        //this.log.printLogLine("selected: " + (String)this.transferCategoryComboBox.getSelectedItem() + "." + (String)this.transferSubcategoryComboBox.getSelectedItem() + "." + (String)this.transferAlbumComboBox.getSelectedItem());

        String categoryFilter = (String)this.transferCategoryComboBox.getSelectedItem();
        String subcategoryFilter = (String)this.transferSubcategoryComboBox.getSelectedItem();
        this.transferUpdateTransferDestinationComboBoxes(categoryFilter, subcategoryFilter, this.transferComboBoxWildcardElement);
        this.transferUpdateTransferTree(categoryFilter, subcategoryFilter, this.transferComboBoxWildcardElement);
    }//GEN-LAST:event_transferSubcategoryComboBoxItemStateChanged

    private void transferAlbumComboBoxItemStateChanged(java.awt.event.ItemEvent evt)//GEN-FIRST:event_transferAlbumComboBoxItemStateChanged
    {//GEN-HEADEREND:event_transferAlbumComboBoxItemStateChanged
        // TODO add your handling code here:
        String categoryFilter = (String)this.transferCategoryComboBox.getSelectedItem();
        String subcategoryFilter = (String)this.transferSubcategoryComboBox.getSelectedItem();
        String albumFilter = (String)this.transferAlbumComboBox.getSelectedItem();
        this.transferUpdateTransferTree(categoryFilter, subcategoryFilter, albumFilter);

    }//GEN-LAST:event_transferAlbumComboBoxItemStateChanged

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton cancelButton;
    private javax.swing.JDialog downloadDialog;
    private javax.swing.JButton folderButton;
    private javax.swing.JLabel folderLabel;
    private javax.swing.JTextField folderTextField;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JTextArea logTextArea;
    private javax.swing.JButton loginCancelButton;
    private javax.swing.JDialog loginDialog;
    private javax.swing.JMenuItem loginMenuItem;
    private javax.swing.JButton loginOkButton;
    private javax.swing.JLabel loginPasswordLabel;
    private javax.swing.JPasswordField loginPasswordPasswordField;
    private javax.swing.JLabel loginUsernameLabel;
    private javax.swing.JTextField loginUsernameTextField;
    private javax.swing.JScrollPane mainAccountScrollPane;
    private javax.swing.JTree mainAccountTree;
    private javax.swing.JButton mainAsyncProcessQueueButton;
    private javax.swing.JButton mainDownloadButton;
    private javax.swing.JButton mainExitButton;
    private javax.swing.JButton mainLoginButton;
    private javax.swing.JScrollPane mainLogtextareaScrollPane;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JButton mainSortButton;
    private javax.swing.JButton mainSyncProcessQueueButton;
    private javax.swing.JButton mainTaggingButton;
    private javax.swing.JButton mainUploadButton;
    private javax.swing.JButton mainVerifyButton;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JButton okButton;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;
    private javax.swing.JLabel transferActionLabel;
    private javax.swing.JComboBox transferAlbumComboBox;
    private javax.swing.JLabel transferAlbumLabel;
    private javax.swing.JButton transferCancelButton;
    private javax.swing.JComboBox transferCategoryComboBox;
    private javax.swing.JLabel transferCategoryLabel;
    private javax.swing.JDialog transferDialog;
    private javax.swing.JFileChooser transferFileChooser;
    private javax.swing.JLabel transferFolderLabel;
    private javax.swing.JTextField transferFolderTextField;
    private javax.swing.JButton transferOkButton;
    private javax.swing.JLabel transferOptionsLabel;
    private javax.swing.JScrollPane transferScrollPane;
    private javax.swing.JButton transferSelectFolderButton;
    private javax.swing.JSeparator transferSeparator1;
    private javax.swing.JSeparator transferSeparator2;
    private javax.swing.JComboBox transferSubcategoryComboBox;
    private javax.swing.JLabel transferSubcategoryLabel;
    private javax.swing.JLabel transferToLabel;
    private javax.swing.JTree transferTree;
    private javax.swing.JDialog waitDialog;
    private javax.swing.JLabel waitMessageLabel;
    // End of variables declaration//GEN-END:variables

    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;

    private JDialog aboutBox;

    //-------------- IView Implementation -----------------------------------
	private GlobalConfig config = null;
    private Logger log = null;
	private Model model = null;

//    private SwingViewNGWaitDialog waitDialog = null;

    private IRootElement smugmugRoot = null;

    // called by the constructor
    public void init(Model model)
    {
        this.config = GlobalConfig.getInstance();
        this.model = model;
		this.model.setView(this);
		this.log = Logger.getInstance();
		this.log.registerView(this);


        this.getFrame().setTitle("jSmugmugBackup v" + this.config.getConstantVersion() + " (experimental GUI)");

        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("<empty>");
        DefaultTreeModel treeModel = new DefaultTreeModel(rootNode);
        this.mainAccountTree.setModel(treeModel);

    }

    public void start()
    {
        /* noop */
    }

//    public ILoginView getLoginMethod()
//    {
//        ILoginView loginToken = new LoginViewSwingNG(this);
//        return loginToken;
//    }

    @Action
    public void mainExitButtonActionPerformed()
    {
        this.model.quitApplication();
    }
    public void updateFileListing(IRootElement smugmugRoot)
    {
        if (smugmugRoot == null) { return; }

        this.smugmugRoot = smugmugRoot;

        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(this.smugmugRoot.getName());

        for (ICategory c : this.smugmugRoot.getCategoryList())
		{
			DefaultMutableTreeNode categoryTreeNode = new DefaultMutableTreeNode(c.getName());

			for (ISubcategory s : c.getSubcategoryList())
			{
				DefaultMutableTreeNode subcategoryTreeNode = new DefaultMutableTreeNode(s.getName());
				for (IAlbum a : s.getAlbumList())
				{
                    String albumTags = "";
                    if (a.getTags() != null)
                    {
                        albumTags = "(" + Helper.getKeywords(a.getTags()) + ")";
                    }

					DefaultMutableTreeNode albumTreeNode = new DefaultMutableTreeNode(a.getName() + albumTags);
					for (IImage i : a.getImageList())
					{
                        String imageTags = "";
                        if (i.getTags() != null)
                        {
                            imageTags = "(" + Helper.getKeywords(i.getTags()) + ")";
                        }

						albumTreeNode.add(new DefaultMutableTreeNode(i.getName() + imageTags));
					}
					subcategoryTreeNode.add(albumTreeNode);
				}
				categoryTreeNode.add(subcategoryTreeNode);
			}

			for (IAlbum a : c.getAlbumList())
			{
				DefaultMutableTreeNode albumTreeNode = new DefaultMutableTreeNode(a.getName());
				for (IImage i : a.getImageList())
				{
					albumTreeNode.add(new DefaultMutableTreeNode(i.getName()));
				}
				categoryTreeNode.add(albumTreeNode);
			}

			rootNode.add(categoryTreeNode);
		}

        this.mainAccountTree.setModel( new DefaultTreeModel(rootNode) );


        /*
		//expand the tree
		for (int row=0; row < this.accountTree.getRowCount()-1; row++)
		{
			this.accountTree.expandRow(row);
		}
        */

        // enable buttons
        this.mainUploadButton.setEnabled(true);
        this.mainDownloadButton.setEnabled(true);
    }
    public void showStatistics(Vector<IAlbum> albumList)
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Action
    public ILoginDialogResult showLoginDialog()
    {
        this.loginDialog.setBounds(this.getFrame().getX()+100, this.getFrame().getY()+100, 250, 150);
        //this.loginDialog.setSize(250, 150);
        this.loginDialog.setVisible(true);

        return this.loginGetLoginDialogResult();
    }
    public ITransferDialogResult showListDialog()
    {
        // listing everything by default
        return new TransferDialogResult(null, null, null, null, null, null, null, /*null,*/ null);
    }
    public ITransferDialogResult showUploadDialog()
    {
        this.transferCustomizeTransferDialog(TransferQueueItemActionEnum.UPLOAD);
        this.transferInitTransferFilter();
        this.transferDialog.setSize(410, 480);
        this.transferDialog.setVisible(true);

        return this.transferGetTransferDialogResult();
    }
    public ITransferDialogResult showSortDialog()
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public ITransferDialogResult showAutotagDialog()
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public ITransferDialogResult showStatisticsDialog()
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public ITransferDialogResult showOsmlayerDialog()
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public ITransferDialogResult showKmllayerDialog()
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public ITransferDialogResult showDownloadDialog()
    {
        
        //this.downloadDialog.setSize(200, 200);
        //this.downloadDialog.setVisible(true);

        this.transferCustomizeTransferDialog(TransferQueueItemActionEnum.DOWNLOAD);
        this.transferInitTransferFilter();
        this.transferDialog.setSize(410, 480);
        this.transferDialog.setVisible(true);

        return this.transferGetTransferDialogResult();
    }
    public ITransferDialogResult showDownloadURLDialog()
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public ITransferDialogResult showVerifyDialog() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public ITransferDialogResult showDeleteDialog() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public void printLog(String text)
    {
        this.logTextArea.append(text);
    }
    public void showError(String errMessage) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public void showBusyStart(String waitingMessage)
    {
        //disable frame, so no mouse events will be recieved
        this.getFrame().setEnabled(false);

        //set message in statusbar
        this.statusMessageLabel.setText(waitingMessage);

        //display waiting dialog
        this.waitSetMessage("please wait ...", waitingMessage);
        this.waitDialog.setSize(200, 150);
        this.waitDialog.setVisible(true);

    }
    public void showBusyStop()
    {        
        this.waitDialog.setVisible(false);
        this.waitSetMessage("please wait ...", "<empty>");

        this.statusMessageLabel.setText("");

        //enable frame
        this.getFrame().setEnabled(true);
    }
    public void addLoginButtonListener(ActionListener listener)
    {
        this.mainLoginButton.addActionListener(listener);
        this.loginMenuItem.addActionListener(listener);
    }
    public void addListButtonListener(ActionListener listener)
    {
        /* todo: nothing to register yet */

        //this.listButton.addActionListener(listener);
    }
    public void addUploadDialogButtonListener(ActionListener listener)
    {
        this.mainUploadButton.addActionListener(listener);
    }
    public void addSortButtonListener(ActionListener listener)
    {
        /* todo: nothing to register yet */
    }
    public void addAutotagButtonListener(ActionListener listener)
    {
        /* todo: nothing to register yet */
    }
    public void addStatisticsButtonListener(ActionListener listener)
    {
        /* todo: nothing to register yet */
    }
    public void addOsmlayerButtonListener(ActionListener listener)
    {
        /* todo: nothing to register yet */
    }
    public void addKmllayerButtonListener(ActionListener listener)
    {
        /* todo: nothing to register yet */
    }
    public void addDownloadDialogButtonListener(ActionListener listener)
    {
        this.mainDownloadButton.addActionListener(listener);
    }
    public void addDownloadURLDialogButtonListener(ActionListener listener)
    {
        /* todo: nothing to register yet */
    }
    public void addVerifyDialogButtonListener(ActionListener listener)
    {
        /* todo: nothing to register yet */
    }
    public void addDeleteDialogButtonListener(ActionListener listener)
    {
        /* todo: nothing to register yet */
    }
    public void addQuitButtonListener(ActionListener listener)
    {
        /* todo: nothing to register yet */
    }
    public void addSyncProcessQueueButtonListener(ActionListener listener)
    {
        this.mainSyncProcessQueueButton.addActionListener(listener);
    }
    public void addASyncProcessQueueStartButtonListener(ActionListener listener)
    {
        this.mainAsyncProcessQueueButton.addActionListener(listener);
    }
    public void notifyASyncProcessQueueFinished()
    {
        this.mainAsyncProcessQueueButton.setEnabled(true);
    }

    //----------------------- main frame ---------------------------------------
    @Action
    public void mainProcessQueueButtonActionPerformed()
    {
        this.mainAsyncProcessQueueButton.setEnabled(false);
    }

    //----------------------- login dialog -------------------------------------
    private ILoginDialogResult loginLoginDialogResult = null;
    private ILoginDialogResult loginGetLoginDialogResult()
    {
        return this.loginLoginDialogResult;
    }
    private void loginResetLoginDialog()
    {
        //making form invisible
        this.loginDialog.setVisible(false);

        //clear input fields
        this.loginUsernameTextField.setText("");
        this.loginPasswordPasswordField.setText("");
    }
    @Action
    public void loginOkButtonActionPerformend()
    {
        //storing username and password
        this.loginLoginDialogResult = new LoginDialogResult(this.loginUsernameTextField.getText(), this.loginPasswordPasswordField.getText());

        this.loginResetLoginDialog();
    }
    @Action
    public void loginCancelButtonActionPerformed()
    {
        this.loginLoginDialogResult = null;

        this.loginResetLoginDialog();
    }

    //--------------- wait dialog ----------------------------------------------
    private void waitSetMessage(String title, String message)
	{
		this.waitDialog.setTitle(title);
        this.waitMessageLabel.setText(message);
	}

    //--------------------- transfer Dialog ------------------------------------
    private ITransferDialogResult transferDialogResult = null;
    private String transferComboBoxWildcardElement = "<empty>";

    private void transferCustomizeTransferDialog(TransferQueueItemActionEnum action)
    {
        if (action.equals(TransferQueueItemActionEnum.DOWNLOAD))
        {
            this.transferActionLabel.setText("download:");
            this.transferFolderLabel.setText("target:");
            this.transferToLabel.setText("download:");
            this.transferOptionsLabel.setText("download options:");

            this.transferComboBoxWildcardElement = "<all>";

        }
        else if (action.equals(TransferQueueItemActionEnum.UPLOAD))
        {
            this.transferActionLabel.setText("upload:");
            this.transferFolderLabel.setText("source:");
            this.transferToLabel.setText("upload to:");
            this.transferOptionsLabel.setText("upload options:");

            this.transferComboBoxWildcardElement = "<auto>";
        }

        //this.transferInitTransferFilter();
    }
    @Action
    public void transferSelectFolderButtonActionPerformed()
    {
        this.transferFileChooser.showOpenDialog(this.getFrame());
        this.transferFolderTextField.setText(this.transferFileChooser.getSelectedFile().getAbsolutePath() + "/");
    }
    @Action
    public void transferOkButtonActionPerformed()
    {
        if ( (!this.transferFolderTextField.getText().equals("")) &&  ((new File(this.transferFolderTextField.getText())).exists()) )
        {
            //making form invisible
            this.transferDialog.setVisible(false);

            this.transferDialogResult = new TransferDialogResult( (String)this.transferCategoryComboBox.getSelectedItem(),
                                                                  (String)this.transferSubcategoryComboBox.getSelectedItem(),
                                                                  (String)this.transferAlbumComboBox.getSelectedItem(),
                                                                  this.transferFolderTextField.getText(),
                                                                  null, null, null, /*null,*/ null );

            //clear input fields
            //...
        }
        else
        {
            JOptionPane jop = new JOptionPane();
            jop.showMessageDialog(this.transferDialog, "sorry, you have to select a valid folder");
        }
    }
    @Action
    public void transferCancelButtonActionPerformed()
    {
        //making form invisible
        this.transferDialog.setVisible(false);

        this.transferDialogResult = null;

        //clear input fields
        //...
    }
    private void transferUpdateTransferDestinationComboBoxes(String categoryFilter, String subcategoryFilter, String albumFilter)
    {

        DefaultComboBoxModel categoryComboBoxModel = new DefaultComboBoxModel();
        for (ICategory c : smugmugRoot.getCategoryList())
        {
            categoryComboBoxModel.addElement(c.getName());
        }
        categoryComboBoxModel.addElement(this.transferComboBoxWildcardElement);
        categoryComboBoxModel.setSelectedItem(categoryFilter);
        this.transferCategoryComboBox.setModel(categoryComboBoxModel);



        DefaultComboBoxModel subcategoryComboBoxModel = new DefaultComboBoxModel();
        for (ICategory c : smugmugRoot.getCategoryList())
        {
            if ( (categoryFilter.equals(this.transferComboBoxWildcardElement)) || (categoryFilter.equals(c.getName())) )
            {
                for (ISubcategory s : c.getSubcategoryList()) { subcategoryComboBoxModel.addElement(s.getName()); }
            }
        }
        subcategoryComboBoxModel.addElement(this.transferComboBoxWildcardElement);
        subcategoryComboBoxModel.setSelectedItem(subcategoryFilter);
        this.transferSubcategoryComboBox.setModel(subcategoryComboBoxModel);



        DefaultComboBoxModel albumComboBoxModel = new DefaultComboBoxModel();
        for (ICategory c : smugmugRoot.getCategoryList())
        {
            if ( (categoryFilter.equals(this.transferComboBoxWildcardElement)) || (categoryFilter.equals(c.getName())) )
            {
                for (ISubcategory s : c.getSubcategoryList())
                {
                    if ( (subcategoryFilter.equals(this.transferComboBoxWildcardElement)) || (subcategoryFilter.equals(s.getName())) )
                    {
                        for (IAlbum a : s.getAlbumList()) { albumComboBoxModel.addElement(a.getName()); }
                    }
                }

                if (subcategoryFilter.equals(this.transferComboBoxWildcardElement))
                {
                    for (IAlbum a : c.getAlbumList()) { albumComboBoxModel.addElement(a.getName()); }
                }
            }

        }
        albumComboBoxModel.addElement(this.transferComboBoxWildcardElement);
        albumComboBoxModel.setSelectedItem(albumFilter);
        this.transferAlbumComboBox.setModel(albumComboBoxModel);

    }
    private void transferUpdateTransferTree(String categoryFilter, String subcategoryFilter, String albumFilter)
    {
        if (smugmugRoot == null) { return; }

        this.smugmugRoot = smugmugRoot;

        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(this.smugmugRoot.getName());

        for (ICategory c : this.smugmugRoot.getCategoryList())
		{
            if ( (categoryFilter.equals(this.transferComboBoxWildcardElement)) || (categoryFilter.equals(c.getName())) )
            {
                DefaultMutableTreeNode categoryTreeNode = new DefaultMutableTreeNode(c.getName());

                for (ISubcategory s : c.getSubcategoryList())
                {
                    if ( (subcategoryFilter.equals(this.transferComboBoxWildcardElement)) || (subcategoryFilter.equals(s.getName())) )
                    {
                        DefaultMutableTreeNode subcategoryTreeNode = new DefaultMutableTreeNode(s.getName());
                        for (IAlbum a : s.getAlbumList())
                        {
                            if ( (albumFilter.equals(this.transferComboBoxWildcardElement)) || (albumFilter.equals(a.getName())) )
                            {
                                String albumTags = "";
                                if (a.getTags() != null)
                                {
                                    albumTags = "(" + Helper.getKeywords(a.getTags()) + ")";
                                }

                                DefaultMutableTreeNode albumTreeNode = new DefaultMutableTreeNode(a.getName() + albumTags);
                                for (IImage i : a.getImageList())
                                {
                                    String imageTags = "";
                                    if (i.getTags() != null)
                                    {
                                        imageTags = "(" + Helper.getKeywords(i.getTags()) + ")";
                                    }

                                    albumTreeNode.add(new DefaultMutableTreeNode(i.getName() + imageTags));
                                }
                                subcategoryTreeNode.add(albumTreeNode);
                            }
                        }
                        categoryTreeNode.add(subcategoryTreeNode);
                    }
                }

                if (subcategoryFilter.equals(this.transferComboBoxWildcardElement))
                {
                    for (IAlbum a : c.getAlbumList())
                    {
                        if ( (albumFilter.equals(this.transferComboBoxWildcardElement)) || (albumFilter.equals(a.getName())) )
                        {
                            DefaultMutableTreeNode albumTreeNode = new DefaultMutableTreeNode(a.getName());
                            for (IImage i : a.getImageList())
                            {
                                albumTreeNode.add(new DefaultMutableTreeNode(i.getName()));
                            }
                            categoryTreeNode.add(albumTreeNode);
                        }
                    }
                }
                
                rootNode.add(categoryTreeNode);
            }

		}


        this.transferTree.setModel( new DefaultTreeModel(rootNode) );

        //expand the tree
		for (int row=0; row < this.transferTree.getRowCount(); row++)
		{
			this.transferTree.expandRow(row);
		}
    }
    private void transferInitTransferFilter()
    {
        this.transferUpdateTransferDestinationComboBoxes(this.transferComboBoxWildcardElement, this.transferComboBoxWildcardElement, this.transferComboBoxWildcardElement);
        this.transferUpdateTransferTree(this.transferComboBoxWildcardElement, this.transferComboBoxWildcardElement, this.transferComboBoxWildcardElement);
    }
    private ITransferDialogResult transferGetTransferDialogResult()
    {
        return this.transferDialogResult;
    }
}
